from datetime import datetime
from typing import Optional, List
from pydantic import BaseModel, EmailStr

# Auth
class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"

class LoginIn(BaseModel):
    email: EmailStr
    password: str

class UserCreate(BaseModel):
    email: EmailStr
    name: str
    password: str

class UserOut(BaseModel):
    id: int
    email: EmailStr
    name: str
    created_at: datetime
    class Config:
        from_attributes = True

# Folders
class FolderCreate(BaseModel):
    name: str
    parent_id: Optional[int] = None

class FolderOut(BaseModel):
    id: int
    name: str
    parent_id: Optional[int]
    order: Optional[int] = 0
    class Config:
        from_attributes = True

class IssueSetFolderIn(BaseModel):
    folder_id: Optional[int] = None

class FolderReorder(BaseModel):
    parent_id: Optional[int] = None
    before_id: Optional[int] = None
    after_id: Optional[int] = None

# Generic link payloads
class LinkIssueIn(BaseModel):
    issue_id: int

class LinkKnowledgeIn(BaseModel):
    knowledge_id: int

class LinkReviewIn(BaseModel):
    review_id: int

# Groups / Tags
class GroupCreate(BaseModel):
    name: str
    description: Optional[str] = None

class GroupOut(BaseModel):
    id: int
    name: str
    description: Optional[str]
    class Config:
        from_attributes = True

class TagCreate(BaseModel):
    name: str
    color: Optional[str] = None

class TagOut(BaseModel):
    id: int
    name: str
    color: Optional[str]
    class Config:
        from_attributes = True

# Issues
class IssueStepIn(BaseModel):
    content: str
    done: bool = False

class IssueStepOut(BaseModel):
    id: int
    content: str
    done: bool
    class Config:
        from_attributes = True

class IssueCreate(BaseModel):
    title: str
    description: Optional[str] = None
    summary: Optional[str] = None
    status: Optional[str] = "todo"
    priority: Optional[str] = "P2"
    importance: Optional[str] = None
    urgency: Optional[str] = None
    deadline: Optional[datetime] = None
    group_id: Optional[int] = None
    steps: Optional[List[IssueStepIn]] = None
    
    # placement
    folder_id: Optional[int] = None

class IssueUpdate(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    summary: Optional[str] = None
    status: Optional[str] = None
    priority: Optional[str] = None
    importance: Optional[str] = None
    urgency: Optional[str] = None
    deadline: Optional[datetime] = None
    group_id: Optional[int] = None
    folder_id: Optional[int] = None

class IssueOut(BaseModel):
    id: int
    title: str
    description: Optional[str]
    summary: Optional[str]
    status: str
    priority: str
    importance: Optional[str]
    urgency: Optional[str]
    deadline: Optional[datetime]
    folder_id: Optional[int] = None
    created_at: datetime
    updated_at: datetime
    is_deleted: Optional[bool] = False
    steps: List[IssueStepOut] = []
    summaries: List["IssueSummaryOut"] = []
    class Config:
        from_attributes = True

class IssueSummaryOut(BaseModel):
    id: int
    content: str
    created_at: datetime
    class Config:
        from_attributes = True

# Knowledge
class KnowledgeCreate(BaseModel):
    title: str
    summary: Optional[str] = None
    body: Optional[str] = None

class KnowledgeOut(BaseModel):
    id: int
    title: str
    summary: Optional[str]
    body: Optional[str]
    created_at: datetime
    is_deleted: Optional[bool] = False
    class Config:
        from_attributes = True
        extra = "allow"

# Review
# Review
class ReviewTaskCreate(BaseModel):
    knowledge_id: int
    card_id: str
    plan_type: str
    due_date: datetime

class ReviewTaskOut(BaseModel):
    id: int
    knowledge_id: int
    card_id: str
    plan_type: str
    status: str
    due_date: datetime
    created_at: datetime
    class Config:
        from_attributes = True

class ReviewPlanRequest(BaseModel):
    knowledge_id: int
    card_ids: List[str]
    plan_type: str # ebbinghaus, daily, weekly, monthly, custom
    custom_interval: Optional[int] = None # days
    custom_dates: Optional[List[datetime]] = None

# Exams
class ExamCreate(BaseModel):
    title: str
    issue_ids: Optional[List[int]] = []
    knowledge_ids: Optional[List[int]] = []
    review_ids: Optional[List[int]] = []

class ExamItemOut(BaseModel):
    id: int
    item_type: str
    ref_id: int
    order: int
    class Config:
        from_attributes = True

class ExamOut(BaseModel):
    id: int
    title: str
    created_at: datetime
    items: List[ExamItemOut] = []
    class Config:
        from_attributes = True
